package com.ruoyi.project.system.service.impl;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.aspectj.lang.annotation.DataScope;
import com.ruoyi.framework.web.domain.TreeSelect;
import com.ruoyi.project.system.domain.SysProfession;
import com.ruoyi.project.system.mapper.SysProfessionMapper;
import com.ruoyi.project.system.service.ISysProfessionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工种 服务实现
 * 
 * @author ruoyi
 */
@Service
public class SysProfessionServiceImpl implements ISysProfessionService
{
    @Resource
    private SysProfessionMapper professionMapper;

    /**
     * 查询工种管理数据
     * 
     * @param profession 工种信息
     * @return 工种信息集合
     */
    @Override
    @DataScope(professionAlias = "p")
    public List<SysProfession> selectProfessionList(SysProfession profession)
    {
        return professionMapper.selectProfessionList(profession);
    }

    /**
     * 构建前端所需要树结构
     * 
     * @param professions 工种列表
     * @return 树结构列表
     */
    @Override
    public List<SysProfession> buildProfessionTree(List<SysProfession> professions)
    {
        List<SysProfession> returnList = new ArrayList<SysProfession>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysProfession Profession : professions)
        {
            tempList.add(Profession.getId());
        }
        for (Iterator<SysProfession> iterator = professions.iterator(); iterator.hasNext();)
        {
            SysProfession Profession = (SysProfession) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(Profession.getParentId()))
            {
                recursionFn(professions, Profession);
                returnList.add(Profession);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = professions;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     * 
     * @param professions 工种列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildProfessionTreeSelect(List<SysProfession> professions)
    {
        List<SysProfession> ProfessionTrees = buildProfessionTree(professions);
        return ProfessionTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据角色ID查询工种树信息
     * 
     * @param roleId 角色ID
     * @return 选中工种列表
     */
    @Override
    public List<Integer> selectProfessionListByRoleId(Long roleId)
    {
        return professionMapper.selectProfessionListByRoleId(roleId);
    }

    /**
     * 根据工种ID查询信息
     * 
     * @param id 工种ID
     * @return 工种信息
     */
    @Override
    public SysProfession selectProfessionById(Long id)
    {
        return professionMapper.selectProfessionById(id);
    }

    /**
     * 根据ID查询所有子工种（正常状态）
     * 
     * @param id 工种ID
     * @return 子工种数
     */
    @Override
    public int selectNormalChildrenProfessionById(Long id)
    {
        return professionMapper.selectNormalChildrenProfessionById(id);
    }

    /**
     * 是否存在子节点
     * 
     * @param id 工种ID
     * @return 结果
     */
    @Override
    public boolean hasChildByProfessionId(Long id)
    {
        int result = professionMapper.hasChildByProfessionId(id);
        return result > 0 ? true : false;
    }

    /**
     * 查询工种是否存在用户
     * 
     * @param id 工种ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkProfessionExistUser(Long id)
    {
        int result = professionMapper.checkProfessionExistUser(id);
        return result > 0 ? true : false;
    }

    /**
     * 校验工种名称是否唯一
     * 
     * @param profession 工种信息
     * @return 结果
     */
    @Override
    public String checkProfessionNameUnique(SysProfession profession)
    {
        Long ProfessionId = StringUtils.isNull(profession.getId()) ? -1L : profession.getId();
        SysProfession info = professionMapper.checkProfessionNameUnique(profession.getName(), profession.getParentId());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != ProfessionId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增保存工种信息
     * 
     * @param profession 工种信息
     * @return 结果
     */
    @Override
    public int insertProfession(SysProfession profession)
    {
        SysProfession info = professionMapper.selectProfessionById(profession.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.PROFESSION_NORMAL.equals(info.getStatus()))
        {
            throw new CustomException("工种停用，不允许新增");
        }
        profession.setAncestors(info.getAncestors() + "," + profession.getParentId());
        return professionMapper.insertProfession(profession);
    }

    /**
     * 修改保存工种信息
     * 
     * @param Profession 工种信息
     * @return 结果
     */
    @Override
    public int updateProfession(SysProfession Profession)
    {
        SysProfession newParentProfession = professionMapper.selectProfessionById(Profession.getParentId());
        SysProfession oldProfession = professionMapper.selectProfessionById(Profession.getId());
        if (StringUtils.isNotNull(newParentProfession) && StringUtils.isNotNull(oldProfession))
        {
            String newAncestors = newParentProfession.getAncestors() + "," + newParentProfession.getId();
            String oldAncestors = oldProfession.getAncestors();
            Profession.setAncestors(newAncestors);
            updateProfessionChildren(Profession.getId(), newAncestors, oldAncestors);
        }
        int result = professionMapper.updateProfession(Profession);
        if (UserConstants.PROFESSION_NORMAL.equals(Profession.getStatus()))
        {
            // 如果该工种是启用状态，则启用该工种的所有上级工种
            updateParentProfessionStatus(Profession);
        }
        return result;
    }

    /**
     * 修改该工种的父级工种状态
     * 
     * @param profession 当前工种
     */
    private void updateParentProfessionStatus(SysProfession profession)
    {
        String updateBy = profession.getUpdateBy();
        profession = professionMapper.selectProfessionById(profession.getId());
        profession.setUpdateBy(updateBy);
        professionMapper.updateProfessionStatus(profession);
    }

    /**
     * 修改子元素关系
     * 
     * @param id 被修改的工种ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateProfessionChildren(Long id, String newAncestors, String oldAncestors)
    {
        List<SysProfession> children = professionMapper.selectChildrenProfessionById(id);
        for (SysProfession child : children)
        {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            professionMapper.updateProfessionChildren(children);
        }
    }

    /**
     * 删除工种管理信息
     * 
     * @param id 工种ID
     * @return 结果
     */
    @Override
    public int deleteProfessionById(Long id)
    {
        return professionMapper.deleteProfessionById(id);
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SysProfession> list, SysProfession t)
    {
        // 得到子节点列表
        List<SysProfession> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysProfession tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                // 判断是否有子节点
                Iterator<SysProfession> it = childList.iterator();
                while (it.hasNext())
                {
                    SysProfession n = (SysProfession) it.next();
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysProfession> getChildList(List<SysProfession> list, SysProfession t)
    {
        List<SysProfession> tlist = new ArrayList<SysProfession>();
        Iterator<SysProfession> it = list.iterator();
        while (it.hasNext())
        {
            SysProfession n = (SysProfession) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysProfession> list, SysProfession t)
    {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
